use std::time::{SystemTime, UNIX_EPOCH};

pub fn assemble_query_config(
    config: (&str, &str),
    query: &mut Vec<(String, String)>,
) -> Result<String, anyhow::Error> {
    let time = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
    let (app_key, app_secret) = config;
    query.push(("appkey".to_owned(), app_key.to_owned()));
    query.push(("time".to_owned(), time.to_string()));
    query.sort_by_key(|k| k.0.to_owned());
    let mut sign_cal = String::new();
    let mut url = String::new();
    for (key, value) in query.iter() {
        sign_cal.push_str(key);
        sign_cal.push_str(value);
        url.push_str(key);
        url.push_str("=");
        url.push_str(value);
        url.push_str("&");
    }
    sign_cal.push_str(app_secret);
    // info!("sign_cal {}", &sign_cal);
    sign_cal = format!("{:x}", md5::compute(sign_cal));
    url.push_str("sign=");
    url.push_str(&sign_cal);
    Ok(url)
}

#[cfg(test)]
mod tests {
    use crate::utils::ids;
    use crate::utils::logutil;
    use crate::utils::query;
    #[test]
    fn test_assemble_query_config() {
        logutil::global_log_init("coolink", "DEBUG");
        let unique_server_id = format!("{}.{}", "default", ids::id_generate_xbit(6));
        let mut ws_query: Vec<(String, String)> =
            vec![("unique_server_id".to_owned(), unique_server_id)];
        let ws_query_result = query::assemble_query_config(
            (&"app_key".to_owned(), &"app_secret".to_owned()),
            &mut ws_query,
        );
        if let Ok(ws_query_str) = &ws_query_result {
            log::info!("assemble_query_config result is {}", ws_query_str);
        }
        assert_eq!(true, ws_query_result.is_ok());
    }
}
